﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace TS2000Control.UserControls
{
    // A delegate type for hooking up ValueChanged notifications. 
    public delegate void ValueChangedEventHandler(object Sender);

    public enum ScanDirection
    {
        Forward,
        Backward
    }

    public partial class TunerControl : UserControl
    {
        public event ValueChangedEventHandler ValueChanged;

        private Image OffScreenImage;
        private Graphics gOffScreen;

        private int _Minimum;
        private int _Maximum;
        private int _tuningStep = 1;
        private int _Value = 0;

        private Timer scanTimer = new Timer();
        private bool _isScanning = false;
        private int _scanDirection = 1;
        private string _bandText = "";

        private float _height;
        private float _width;

        double[] cbfreqs = new double[40]
            { 
                26.965, 26.975, 26.985, 27.005, 27.015, 27.025, 27.035, 27.055, 27.065, 27.075,
                27.085, 27.105, 27.115, 27.125, 27.135, 27.155, 27.165, 27.175, 27.185, 27.205,
                27.215, 27.225, 27.255, 27.235, 27.245, 27.265, 27.275, 27.285, 27.295, 27.305, 
                27.315, 27.325, 27.335, 27.345, 27.355, 27.365, 27.375, 27.385, 27.395, 27.405
            };


        int x = 0;
        int lastX = 0;


        public int Minimum
        {
            get { return _Minimum; }
            set { _Minimum = value; }
        }

        public int Maximum
        {
            get { return _Maximum; }
            set { _Maximum = value; }
        }

        public int Value
        {
            get { return _Value; }
            set
            {
                _Value = value;

                _bandText = "";
                if (_Value >= 1800000 && _Value <= 2000000) _bandText = "160m";
                if (_Value >= 3500000 && _Value <= 4000000) _bandText = "80m";
                if (_Value >= 7000000 && _Value <= 7300000) _bandText = "40m";
                if (_Value >= 14000000 && _Value <= 14350000) _bandText = "20m";
                if (_Value >= 18068000 && _Value <= 18168000) _bandText = "17m";
                if (_Value >= 21000000 && _Value <= 21450000) _bandText = "15m";
                if (_Value >= 24890000 && _Value <= 24990000) _bandText = "12m";
                if (_Value >= 28000000 && _Value <= 29700000) _bandText = "10m";
                if (_Value >= 50000000 && _Value <= 54000000) _bandText = "6m";
                if (_Value >= 144000000 && _Value <= 148000000) _bandText = "2m";
                if (_Value >= 420000000 && _Value <= 450000000) _bandText = "70cm";
                if (_Value == 5000000 || _Value == 10000000) _bandText = "WWV";

                for(int x=0; x<40; x++)
                {
                    if (_Value == Convert.ToInt32(cbfreqs[x] * 1000000))
                    {
                        _bandText = "CB Ch" + (x + 1).ToString();
                        break;
                    }

                }

                // need to redraw 
                Refresh();
                // call delegate  
                OnValueChanged(this);
            }
        }

        public int TuningStep
        {
            get { return _tuningStep; }
            set { _tuningStep = value; }
        }

        public bool IsScanning
        {
            get { return _isScanning; }
        }

        public string BandText
        {
            get { return _bandText; }
        }

        public TunerControl()
        {
            InitializeComponent();

            scanTimer.Interval = 50;
            scanTimer.Tick += scanTimer_Tick;
        }

        private void TunerControl_Load(object sender, EventArgs e)
        {            
            this.OffScreenImage = new Bitmap(this.Width, this.Height);                             
            this.gOffScreen = Graphics.FromImage(OffScreenImage);
            this.DoubleBuffered = true;
        }

        protected virtual void OnValueChanged(object sender)
        {
            if (ValueChanged != null)
                ValueChanged(sender);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            _height = this.Height;
            _width = this.Width;
            int largeDivision = x;
            int smallDivision = x;

            gOffScreen.Clear(this.BackColor);

            Pen p1 = new Pen(Color.Lime);
            Pen p0 = new Pen(Color.White);
            System.Drawing.SolidBrush myBrush = new System.Drawing.SolidBrush(System.Drawing.Color.OrangeRed);

            // Here backward
            int ctr = this._Value;
            for (float l =_width /2; l >0; ctr -= 10)
            {
                double z1 = Convert.ToDouble(ctr) / 10;

                /*if (z1 >= 712500 && z1 <= 730000)
                {
                    gOffScreen.FillRectangle(myBrush, l, _height-20, 10, 10);
                    gOffScreen.DrawString("SSB", new Font("Arial", 8), new SolidBrush(Color.White), _width / 2, _height-20, StringFormat.GenericDefault);
                }*/
                //if (Math.Floor(z1) == z1)
                //    gOffScreen.DrawLine(p1, l, 40, l, _height - 40);

                z1 /= 10;
                
                if (Math.Floor(z1) == z1)
                    gOffScreen.DrawLine(p1, l, 40, l, _height - 40);

                z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p1, l, 30, l, _height - 30);
                    gOffScreen.DrawString((z1 / 1000).ToString("###.##0"), new Font("Arial", 8), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                    goto skip;
                }

                z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p1, l, 20, l, _height - 20);
                    gOffScreen.DrawString((z1 / 100).ToString("###.#0"), new Font("Arial", 10), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                    goto skip;
                }

               /* z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p1, l, 10, l, _height - 10);
                    gOffScreen.DrawString((z1 / 100).ToString("###.#0"), new Font("Arial", 10), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                    goto skip;
                }

                z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p0, l, 10, l, _height - 10);
                    gOffScreen.DrawString((z1 / 100).ToString("###.#0"), new Font("Arial", 10), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                    goto skip;
                }*/


            skip:
                l -= 1;
            }

            // Here forward
            ctr = this._Value;
            for (float l = _width / 2; l < _width; ctr += 10)
            {
                double z1 = Convert.ToDouble(ctr) / 10;

                /*if (z1 >= 712500 && z1 <= 730000)
                {
                    gOffScreen.FillRectangle(myBrush, l, _height - 20, 10, 10);
                    gOffScreen.DrawString("SSB", new Font("Arial", 8), new SolidBrush(Color.White), _width / 2, _height - 20, StringFormat.GenericDefault);
                }*/

                //if (Math.Floor(z1) == z1)
                //    gOffScreen.DrawLine(p1, l, 40, l, _height - 40);

                z1 /= 10;

                if (Math.Floor(z1) == z1)
                    gOffScreen.DrawLine(p1, l, 40, l, _height - 40);

                z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p1, l, 30, l, _height - 30);
                    gOffScreen.DrawString((z1 / 1000).ToString("###.##0"), new Font("Arial", 8), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                    goto skip;
                }

                z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p1, l, 20, l, _height - 20);
                    gOffScreen.DrawString((z1 / 100).ToString("###.#0"), new Font("Arial", 10), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                    goto skip;
                }
                
               /* z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p1, l, 10, l, _height - 10);
                    gOffScreen.DrawString((z1 / 100).ToString("###.#0"), new Font("Arial", 10), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                    goto skip;
                }

                z1 /= 10;

                if (Math.Floor(z1) == z1)
                {
                    gOffScreen.DrawLine(p0, l, 10, l, _height - 10);
                    gOffScreen.DrawString((z1/100).ToString("###.#0"), new Font("Arial", 10), new SolidBrush(Color.White), l, 10, StringFormat.GenericDefault);
                }*/


            skip:

                l += 1;
            }

            // Draw top line
            gOffScreen.DrawLine(p1, 0, 10, _width, 10);
            // Draw bottom line
            gOffScreen.DrawLine(p1, 0, _height - 10, _width, _height - 10);

            g.DrawImage(OffScreenImage, 0, 0);


            // Draw tuner selector
            Pen p2 = new Pen(Color.Red);
            g.DrawLine(p2, _width / 2, 0, _width / 2, _height);
        }

        private void TunerControl_MouseMove(object sender, MouseEventArgs e)
        {
            int direction = 0;

            if (e.Button == MouseButtons.Left)
            {
                int dx = e.X - lastX;

                if (dx == 0) return;

                direction = (dx > 0) ? TuningStep *10 : -TuningStep*10;
                lastX = e.X;
                //x += direction;

                Value = _Value + (direction * -TuningStep);
            }
        }

        public void ScanStart(ScanDirection s)
        {
            _isScanning = true;

            if (s == ScanDirection.Forward)
                _scanDirection = 1;
            else
                _scanDirection = -1;

            scanTimer.Start();
        }

        public void ScanStop()
        {
            _isScanning = false;
            scanTimer.Stop();
        }

        void scanTimer_Tick(object sender, EventArgs e)
        {
            //int direction = ;

            Value = _Value + (_scanDirection * (TuningStep * TuningStep * 10));
        }
    }
}
